package com.imageim.yimirror.common.ui.face;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.imageim.yimirror.R;
import com.imageim.yimirror.common.EnviromentConfig;
import com.martin.ads.omoshiroilib.camera.CameraEngine;
import com.martin.ads.omoshiroilib.util.BitmapUtils;
import com.sensetime.stmobileapi.STMobile106;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by Bruce.Zhou on 2017/12/07
 */
public class DrawFaceView extends SurfaceView implements Runnable {

    //    private STMobile106[] faceInfoList;
    private Paint paint;
    private SurfaceHolder holder;
    private boolean isDrawing = false;
    //    private ConcurrentHashMap<Integer, ScanerBean> scanerMap;
    private ScanerBean maxScannerBean;
    private Bitmap fourCornor;
    private Bitmap scannerLine;
    //    private Bitmap innerCircleBitmap;
    private Bitmap srcCircleBitmap;
    public static int TRANSFORM_DX = 0;
    private static final int SCAN_ONCE_TIME = 40;
    private static float CIRCLE_ROTATE_TIME = 3.2f; // 圆圈旋转速度
    private boolean canDraw = true;
    private Rect faceRectSrc = new Rect();
    private Rect faceRectDst = new Rect();
    private int basicColor;

    public DrawFaceView(Context context) {
        super(context);
        init();
    }

    public DrawFaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DrawFaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paint = new Paint();
        basicColor = Color.parseColor("#0cf5fc");
        paint.setStrokeWidth(4);
        paint.setTextSize(40);
        paint.setAntiAlias(true);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.GREEN);
        paint.setDither(true);
        setZOrderOnTop(true);
        holder = getHolder();
        holder.setFormat(PixelFormat.TRANSLUCENT);
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                if (isDrawing == false) {
                    isDrawing = true;
                    new Thread(DrawFaceView.this).start();
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
                // 绘制视图从4：3转3:4后，x坐标的偏差
                if (EnviromentConfig.IS_LANDSCAPE) {
                    TRANSFORM_DX = (int) ((getHeight() * CameraEngine.preferredRatio - getHeight() * (1 / CameraEngine.preferredRatio)) / 2);
                } else {
                    TRANSFORM_DX = 0;
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                isDrawing = false;
            }
        });
        //        scanerMap = new ConcurrentHashMap<>();
        initBitmap();
    }

    private void initBitmap() {
        srcCircleBitmap = BitmapUtils.loadBitmapFromRaw(getContext(), R.mipmap.in_circle);
    }

    public void setFaceInfoList(STMobile106[] faceInfoList) {
        //        this.faceInfoList = faceInfoList;
        updateScanerMap(faceInfoList);
        //        draw();
    }

    private void updateScanerMap(STMobile106[] faceInfoList) {
        //        ConcurrentHashMap<Integer, ScanerBean> newScanerMap = new ConcurrentHashMap<>();
        //        if (faceInfoList != null && faceInfoList.length > 0) {
        //            for (STMobile106 face : faceInfoList) {
        //                if (scanerMap.containsKey(face.ID)) {
        //                    ScanerBean sb = scanerMap.get(face.ID);
        //                    sb.setFace(face);
        //                    newScanerMap.put(face.ID, sb);
        //                } else {
        //                    ScanerBean sb = new ScanerBean();
        //                    sb.setFace(face);
        //                    sb.setScanY(0);
        //                    newScanerMap.put(face.ID, sb);
        //                }
        //            }
        //        }
        //        scanerMap = newScanerMap;
        // ----------------------------------------------------
        if (faceInfoList != null && faceInfoList.length > 0) {
            STMobile106 maxFace = null; // 最大的并且在有效画面区域的人脸
            if (faceInfoList.length > 1) {
                List<STMobile106> faceList = Arrays.asList(faceInfoList);
                Collections.sort(faceList, faceSizeComparator);
                for (int i = 0; i < faceList.size(); i++) {
                    if (isFaceInValidArea(faceList.get(i))) {
                        maxFace = faceList.get(i);
                        break;
                    }
                }
                if (maxFace == null) {
                    maxFace = faceList.get(0);
                }
            } else {
                maxFace = faceInfoList[0];
            }
            if (maxScannerBean == null) {
                maxScannerBean = new ScanerBean();
                maxScannerBean.setScanY(0);
                maxScannerBean.setFace(maxFace);
            } else {
                //                if (maxScannerBean.getFace().ID != maxFace.ID) {
                ////                    maxScannerBean.setScanY(0);
                //                }
                maxScannerBean.setFace(maxFace);
            }
        } else {
            maxScannerBean = null;
        }
    }

    public Comparator<STMobile106> faceSizeComparator = new Comparator<STMobile106>() {
        @Override
        public int compare(STMobile106 f1, STMobile106 f2) {
            return f2.getRect().width() - f1.getRect().width();
        }
    };

    public void draw() {
        try {
            Canvas canvas = holder.lockCanvas();
            if (canvas == null) {
                return;
            }
            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            if (canDraw) {
                drawScaner(canvas);
            }

            if (holder != null) {
                holder.unlockCanvasAndPost(canvas);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //        // test
        //        paint.setStyle(Paint.Style.FILL);
        //        canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
        //        paint.setStyle(Paint.Style.STROKE);

    }

    private void doLogic() {
        //        Set<Integer> faceIds = scanerMap.keySet();
        //        for (Iterator<Integer> iterator = faceIds.iterator(); iterator.hasNext();) {
        //            int faceId = iterator.next();
        //            ScanerBean sb = scanerMap.get(faceId);
        ScanerBean sb = maxScannerBean;
        //            if (sb == null) {
        //                continue;
        //            }
        if (sb == null || !isFaceInValidArea(sb.getFace())) {
            return;
        }
        List<CircleBean> cbList = sb.getCircleBeanList();
        for (int i = 0; i < cbList.size(); i++) {
            if (i % 2 == 0) {
                CIRCLE_ROTATE_TIME = -CIRCLE_ROTATE_TIME;
            }
            CircleBean cb = cbList.get(i);
            ArcBean outBigArc = cb.getOutBigArc();
            outBigArc.setStartAngle(outBigArc.getStartAngle() + CIRCLE_ROTATE_TIME);

            ArcBean outSmallArc = cb.getOutSmallArc();
            outSmallArc.setStartAngle(outSmallArc.getStartAngle() + CIRCLE_ROTATE_TIME);

            ArcBean inBigArc = cb.getInBigArc();
            inBigArc.setStartAngle(inBigArc.getStartAngle() - CIRCLE_ROTATE_TIME);

            ArcBean inMiddleArc = cb.getInMiddleArc();
            inMiddleArc.setStartAngle(inMiddleArc.getStartAngle() - CIRCLE_ROTATE_TIME);

            ArcBean inSmallArc = cb.getInSmallArc();
            inSmallArc.setStartAngle(inSmallArc.getStartAngle() - CIRCLE_ROTATE_TIME);
        }
        //        }
    }

    @Override
    public void run() {
        while (isDrawing) {
            //            Log.e("draw", "draw face");
            doLogic();
            draw();
        }
    }

    private void drawScaner(Canvas canvas) {
        //        Set<Integer> faceIds = scanerMap.keySet();
        //        for (Iterator<Integer> iterator = faceIds.iterator(); iterator.hasNext();) {
        //            int faceId = iterator.next();
        //            ScanerBean sb = scanerMap.get(faceId);
        ScanerBean sb = maxScannerBean;
        //            if (sb == null) {
        //                continue;
        //            }
        if (EnviromentConfig.IS_LANDSCAPE) {
            if (sb == null
                    || !isFaceInValidArea(sb.getFace())
            ) {
                return;
            }
        } else {
            if (sb == null) {
                return;
            }
        }
        STMobile106 face = sb.getFace();
        if (fourCornor == null) {
            fourCornor = BitmapUtils.loadBitmapFromRaw(getContext(), R.mipmap.four_cornor);
        }
        if (scannerLine == null) {
            scannerLine = BitmapUtils.loadBitmapFromRaw(getContext(), R.mipmap.scaner);
        }
        // Draw face rect.
        Rect faceRect = face.getRect();

        //            paint.setColor(Color.RED);
        //            paint.setTextSize(36);
        ////            paint.setStyle(Paint.Style.FILL);
        //            canvas.drawText("facePos : "  + faceRect.left + "," + faceRect.top + ", "
        //                    + faceRect.redPacketWidth() + "," +faceRect.redPacketHeight(), 100, 100, paint);

        int left;
        int top;
        if (EnviromentConfig.IS_MIRROR) {
            if (EnviromentConfig.IS_LANDSCAPE) {
                left = faceRect.left * 2 - TRANSFORM_DX;
                top = faceRect.top * 2;
            } else { // Adapter portrait screen.
                left = (int) (getWidth() - faceRect.left * CameraEngine.transRate - faceRect.width() * 2 + face.getRect().width() / 4.4f);
                top = (int) (getHeight() - faceRect.top * CameraEngine.transRate - faceRect.height() * 2);
            }
        } else {
            left = getWidth() - faceRect.right * 2 + TRANSFORM_DX;
            top = faceRect.top * 2;
        }
        int width = (faceRect.right - faceRect.left) * 2;
        int height = (faceRect.bottom - faceRect.top) * 2;
        faceRectSrc.set(0, 0, fourCornor.getWidth(), fourCornor.getHeight());
        faceRectDst.set(left, top, left + width, top + height);
        canvas.drawBitmap(fourCornor, faceRectSrc, faceRectDst, paint);
        // Draw scanner line
        float speed = height * 1.0f / SCAN_ONCE_TIME;
        if (!sb.isScanUp()) {
            if (sb.getScanY() < height - 10) {
                sb.setScanY(sb.getScanY() + speed);
                if (sb.getScanY() >= height - 10) {
                    sb.setScanY(height - 10);
                    sb.setScanUp(true);
                }
            } else {
                sb.setScanY(height - 10.1f);
            }
        } else {
            if (sb.getScanY() > 10) {
                sb.setScanY(sb.getScanY() - speed);
                if (sb.getScanY() <= 10) {
                    sb.setScanY(10);
                    sb.setScanUp(false);
                }
            } else {
                sb.setScanY(10.1f);
            }
        }

        Matrix lineMatrix = new Matrix();
        float lineScaleX = (1.0f * width) / scannerLine.getWidth();
        float lineScaleY = lineScaleX;
        lineMatrix.postScale(lineScaleX, lineScaleY);
        lineMatrix.postTranslate(left, top - scannerLine.getHeight() * lineScaleY / 2 + sb.getScanY());
        canvas.drawBitmap(scannerLine, lineMatrix, paint);
        // Draw face attr lines.
        drawFaceAttr(canvas, sb, lineScaleX);
    }

    private Path path1 = new Path();
    private Path path2 = new Path();
    private Path path3 = new Path();
    private Path path4 = new Path();

    private void drawFaceAttr(Canvas canvas, ScanerBean sb, float scale) {

        STMobile106 face = sb.getFace();
        //        PointF[] points = face.getPointsArray();
        //        if (points != null && points.length > 0) {
        //            for (int k = 0; k < points.length; k++) {
        //                PointF p = points[k];
        //                float cx;
        //                float cy;
        //                if (EnviromentConfig.IS_MIRROR) {
        //                    cx = p.x * 2 - TRANSFORM_DX;
        //                    cy = p.y * 2;
        //                } else {
        //                    cx =  getWidth() - p.x * 2 + TRANSFORM_DX;
        //                    cy =  p.y * 2;
        //                }
        //                float radius = 1f;
        ////                canvas.drawCircle(cx, cy, radius, paint);
        //                paint.setTextSize(16);
        //                canvas.drawText("" + k, cx, cy, paint);
        //            }
        //            paint.setColor(Color.RED);
        //            paint.setStrokeWidth(8);
        //            canvas.drawPoint(getWidth() - points[36].x*2 + TRANSFORM_DX, points[36].y * 2, paint);
        //            canvas.drawPoint(getWidth() - points[39].x*2 + TRANSFORM_DX, points[39].y * 2, paint);
        //            canvas.drawPoint(getWidth() - points[43].x*2 + TRANSFORM_DX, points[43].y * 2, paint);
        //            canvas.drawPoint(getWidth() - points[46].x*2 + TRANSFORM_DX, points[46].y * 2, paint);
        //            canvas.drawPoint(getWidth() - points[63].x*2 + TRANSFORM_DX, points[63].y * 2, paint);
        //            paint.setColor(Color.GREEN);
        //        }

        // Draw face attr line
        paint.setStrokeWidth(1);
        paint.setColor(basicColor);
        PointF[] pathPoints = PathInfo.getPoints();
        PointF[] facePoints = face.getPointsArray();
        //        path1 = new Path();
        path1.reset();
        float attrX1;
        float attrY1;
        if (EnviromentConfig.IS_MIRROR) {
            if (EnviromentConfig.IS_LANDSCAPE) {
                attrX1 = facePoints[ScanerBean.attrPointIndexs[0]].x * 2 - TRANSFORM_DX;
                attrY1 = facePoints[ScanerBean.attrPointIndexs[0]].y * 2;
            } else {
                attrX1 = (int) (getWidth() - facePoints[ScanerBean.attrPointIndexs[0]].x * CameraEngine.transRate);
                attrY1 = (int) (getHeight() - facePoints[ScanerBean.attrPointIndexs[0]].y * CameraEngine.transRate);
            }
        } else {
            attrX1 = getWidth() - facePoints[ScanerBean.attrPointIndexs[0]].x * 2 + TRANSFORM_DX;
            attrY1 = facePoints[ScanerBean.attrPointIndexs[0]].y * 2;
        }
        path1.moveTo(attrX1, attrY1);
        float middleX;
        float middleY;
        float endX;
        float endY;
        if (EnviromentConfig.IS_LANDSCAPE) {
            middleX = attrX1 + pathPoints[0].x * scale;
            middleY = attrY1 + pathPoints[0].y * scale;
            endX = attrX1 + pathPoints[1].x * scale;
            endY = attrY1 + pathPoints[1].y * scale;
        } else {
            middleX = attrX1 + pathPoints[0].x * scale;
            middleY = attrY1 + pathPoints[0].y * scale;
            endX = attrX1 + pathPoints[1].x * scale;
            endY = attrY1 + pathPoints[1].y * scale;
        }
        path1.lineTo(middleX, middleY);
        path1.lineTo(endX, endY);
        canvas.drawPath(path1, paint);


        //        path2 = new Path();
        path2.reset();
        float attrX2;
        float attrY2;
        if (EnviromentConfig.IS_MIRROR) {
            if (EnviromentConfig.IS_LANDSCAPE) {
                attrX2 = facePoints[ScanerBean.attrPointIndexs[1]].x * 2 - TRANSFORM_DX;
                attrY2 = facePoints[ScanerBean.attrPointIndexs[1]].y * 2;
            } else {
                attrX2 = (int) (getWidth() - facePoints[ScanerBean.attrPointIndexs[1]].x * CameraEngine.transRate);
                attrY2 = (int) (getHeight() - facePoints[ScanerBean.attrPointIndexs[1]].y * CameraEngine.transRate);
            }
        } else {
            attrX2 = getWidth() - facePoints[ScanerBean.attrPointIndexs[1]].x * 2 + TRANSFORM_DX;
            attrY2 = facePoints[ScanerBean.attrPointIndexs[1]].y * 2;
        }
        path2.moveTo(attrX2, attrY2);
        float middleX2 = attrX2 + pathPoints[2].x * scale;
        float middleY2 = attrY2 + pathPoints[2].y * scale;
        float endX2 = attrX2 + pathPoints[3].x * scale;
        float endY2 = attrY2 + pathPoints[3].y * scale;
        path2.lineTo(middleX2, middleY2);
        path2.lineTo(endX2, endY2);
        canvas.drawPath(path2, paint);


        //        path3 = new Path();
        path3.reset();
        float attrX3;
        float attrY3;
        if (EnviromentConfig.IS_MIRROR) {
            if (EnviromentConfig.IS_LANDSCAPE) {
                attrX3 = facePoints[ScanerBean.attrPointIndexs[2]].x * 2 - TRANSFORM_DX - face.getRect().width() / 5.0f;
                attrY3 = facePoints[ScanerBean.attrPointIndexs[2]].y * 2;
            } else {
                attrX3 = (int) (getWidth() - facePoints[ScanerBean.attrPointIndexs[2]].x * CameraEngine.transRate
                        - face.getRect().width() / 5.0f);
                attrY3 = (int) (getHeight() - facePoints[ScanerBean.attrPointIndexs[2]].y * CameraEngine.transRate);
            }
        } else {
            attrX3 = getWidth() - facePoints[ScanerBean.attrPointIndexs[2]].x * 2 + TRANSFORM_DX + face.getRect().width() / 5.0f;
            attrY3 = facePoints[ScanerBean.attrPointIndexs[2]].y * 2;
        }
        path3.moveTo(attrX3, attrY3);
        float middleX3 = attrX3 + pathPoints[4].x * scale;
        float middleY3 = attrY3 + pathPoints[4].y * scale;
        float endX3 = attrX3 + pathPoints[5].x * scale;
        float endY3 = attrY3 + pathPoints[5].y * scale;
        path3.lineTo(middleX3, middleY3);
        path3.lineTo(endX3, endY3);
        canvas.drawPath(path3, paint);


        //        path4 = new Path();
        path4.reset();
        float attrX4;
        float attrY4;
        if (EnviromentConfig.IS_MIRROR) {
            if (EnviromentConfig.IS_LANDSCAPE) {
                attrX4 = facePoints[ScanerBean.attrPointIndexs[3]].x * 2 - TRANSFORM_DX;
                attrY4 = facePoints[ScanerBean.attrPointIndexs[3]].y * 2;
            } else {
                attrX4 = (int) (getWidth() - facePoints[ScanerBean.attrPointIndexs[3]].x * CameraEngine.transRate);
                attrY4 = (int) (getHeight() - facePoints[ScanerBean.attrPointIndexs[3]].y * CameraEngine.transRate);
            }
        } else {
            attrX4 = getWidth() - facePoints[ScanerBean.attrPointIndexs[3]].x * 2 + TRANSFORM_DX;
            attrY4 = facePoints[ScanerBean.attrPointIndexs[3]].y * 2;
        }
        path4.moveTo(attrX4, attrY4);
        float middleX4 = attrX4 + pathPoints[6].x * scale;
        float middleY4 = attrY4 + pathPoints[6].y * scale;
        float endX4 = attrX4 + pathPoints[7].x * scale;
        float endY4 = attrY4 + pathPoints[7].y * scale;
        path4.lineTo(middleX4, middleY4);
        path4.lineTo(endX4, endY4);
        canvas.drawPath(path4, paint);

        // --------- Draw circle -----------
        paint.setStrokeWidth(2);
        List<CircleBean> circleBeanList = sb.getCircleBeanList();
        for (int i = 0; i < circleBeanList.size(); i++) {
            paint.setColor(basicColor);
            CircleBean cb = circleBeanList.get(i);
            switch (i) {
                case 1:
                    endX = endX2;
                    endY = endY2;
                    break;
                case 2:
                    endX = endX3;
                    endY = endY3;
                    break;
                case 3:
                    endX = endX4;
                    endY = endY4;
                    break;
                default:
            }
            // draw out big arc
            float arcSize = cb.getOutBigArc().getSize() * scale;
            float arcRectLeft = endX - arcSize;
            float arcRectTop = endY - arcSize;
            mRectF.set(arcRectLeft, arcRectTop
                    , arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2);
            canvas.drawArc(mRectF, cb.getOutBigArc().getStartAngle(), cb.getOutBigArc().getSweepAngle(), false, paint);
            //            canvas.drawArc(new RectF(arcRectLeft, arcRectTop
            //                            , arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2)
            //                    , cb.getOutBigArc().getStartAngle(), cb.getOutBigArc().getSweepAngle()
            //                    , false, paint);

            // draw out small arc
            arcSize = cb.getOutSmallArc().getSize() * scale;
            arcRectLeft = endX - arcSize;
            arcRectTop = endY - arcSize;

            mRectF.set(arcRectLeft, arcRectTop, arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2);
            canvas.drawArc(mRectF, cb.getOutSmallArc().getStartAngle(), cb.getOutSmallArc().getSweepAngle()
                    , false, paint);
            //            canvas.drawArc(new RectF(arcRectLeft, arcRectTop
            //                            , arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2)
            //                    , cb.getOutSmallArc().getStartAngle(), cb.getOutSmallArc().getSweepAngle()
            //                    , false, paint);


            // Draw inner filled circle.
            float imageWidth = 2 * arcSize;
            Matrix icMatrix = new Matrix();
            float icScale = imageWidth / srcCircleBitmap.getWidth();
            icMatrix.postScale(icScale, icScale);
            if (srcCircleBitmap == null || srcCircleBitmap.isRecycled()) {
                srcCircleBitmap = BitmapUtils.loadBitmapFromRaw(getContext(), R.mipmap.in_circle);
            }
            Bitmap innerCircleBitmap = Bitmap.createBitmap(srcCircleBitmap, 0, 0
                    , srcCircleBitmap.getWidth(), srcCircleBitmap.getHeight(),
                    icMatrix, true);
            canvas.drawBitmap(innerCircleBitmap, arcRectLeft, arcRectTop, paint);

            // draw in big arc
            arcSize = cb.getInBigArc().getSize() * scale;
            arcRectLeft = endX - arcSize;
            arcRectTop = endY - arcSize;
            mRectF.set(arcRectLeft, arcRectTop
                    , arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2);
            canvas.drawArc(mRectF, cb.getInBigArc().getStartAngle(), cb.getInBigArc().getSweepAngle()
                    , false, paint);
            //            canvas.drawArc(new RectF(arcRectLeft, arcRectTop
            //                            , arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2)
            //                    , cb.getInBigArc().getStartAngle(), cb.getInBigArc().getSweepAngle()
            //                    , false, paint);

            // draw in middle arc
            arcSize = cb.getInMiddleArc().getSize() * scale;
            arcRectLeft = endX - arcSize;
            arcRectTop = endY - arcSize;
            mRectF.set(arcRectLeft, arcRectTop
                    , arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2);
            canvas.drawArc(mRectF, cb.getInMiddleArc().getStartAngle(), cb.getInMiddleArc().getSweepAngle()
                    , false, paint);
            //            canvas.drawArc(new RectF(arcRectLeft, arcRectTop
            //                            , arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2)
            //                    , cb.getInMiddleArc().getStartAngle(), cb.getInMiddleArc().getSweepAngle()
            //                    , false, paint);

            // draw int small arc
            arcSize = cb.getInSmallArc().getSize() * scale;
            arcRectLeft = endX - arcSize;
            arcRectTop = endY - arcSize;
            mRectF.set(arcRectLeft, arcRectTop
                    , arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2);
            canvas.drawArc(mRectF, cb.getInSmallArc().getStartAngle(), cb.getInSmallArc().getSweepAngle()
                    , false, paint);
            //            canvas.drawArc(new RectF(arcRectLeft, arcRectTop
            //                            , arcRectLeft + arcSize * 2, arcRectTop + arcSize * 2)
            //                    , cb.getInSmallArc().getStartAngle(), cb.getInSmallArc().getSweepAngle()
            //                    , false, paint);
            paint.setColor(Color.WHITE);
            paint.setTextSize(40 * scale);
            paint.setStyle(Paint.Style.FILL);
            canvas.drawText(cb.getText(), endX - paint.getTextSize() / 2
                    , endY + paint.getTextSize() / 2, paint);
            paint.setStyle(Paint.Style.STROKE);
        } // circle

        paint.setColor(Color.GREEN);
    }


    private RectF mRectF = new RectF();


    /**
     * 人脸是否在有效扫描区域
     *
     * @param face
     * @return
     */
    public boolean isFaceInValidArea(STMobile106 face) {
        if (EnviromentConfig.IS_LANDSCAPE) {
            if (TRANSFORM_DX == 0) {
                return false;
            }
        }

        if (face == null) {
            return false;
        }
        Rect faceRect = face.getRect();
        float left;
        float top;
        if (EnviromentConfig.IS_MIRROR) {
            if (EnviromentConfig.IS_LANDSCAPE) {
                left = faceRect.left * 2 - TRANSFORM_DX;
                top = faceRect.top * 2;
            } else {
                left = (int) (getWidth() - faceRect.left * CameraEngine.transRate - faceRect.width() * 2);
                top = (int) (getHeight() - faceRect.top * CameraEngine.transRate - faceRect.height() * 2);
            }
        } else {
            left = getWidth() - faceRect.right * 2 + TRANSFORM_DX;
            top = faceRect.top * 2;
        }
        float faceWidth = faceRect.width() * 2;
        float faceHeight = faceRect.height() * 2;

        ////        Canvas canvas = holder.lockCanvas();
        //        if (canvas != null) {
        //            canvas.drawRect(new RectF(0, 0,
        //                    getWidth(), screenHeight), paint);
        //        }
        ////        holder.unlockCanvasAndPost(canvas);

        return (left >= 0) && (left <= getWidth() - faceWidth)
                && (top <= getHeight() - faceHeight);
    }

    public boolean isFaceInValidAreaUseForBanner(STMobile106 face) {
        if (face == null) {
            return false;
        }
        Rect faceRect = face.getRect();
        float left;
        float top;
        if (EnviromentConfig.IS_MIRROR) {
            if (EnviromentConfig.IS_LANDSCAPE) {
                left = faceRect.left * 2;
                top = faceRect.top * 2;
            } else {
                left = (int) (getWidth() - faceRect.left * CameraEngine.transRate - faceRect.width() * 2);
                top = (int) (getHeight() - faceRect.top * CameraEngine.transRate - faceRect.height() * 2);
            }
        } else {
            left = getWidth() - faceRect.right * 2 + TRANSFORM_DX;
            top = faceRect.top * 2;
        }
        float faceWidth = (faceRect.right - faceRect.left) * 2;
        float faceHeight = (faceRect.bottom - faceRect.top) * 2;
        return (left >= 0) && (left <= getWidth() - faceWidth)
                && (top <= getHeight() - faceHeight);
    }

    public void stopDraw() {
        canDraw = false;
    }

    public void resumeDraw() {
        canDraw = true;
    }

    public void finish() {
        isDrawing = false;
        canDraw = false;
        if (fourCornor != null && !fourCornor.isRecycled()) {
            fourCornor.recycle();
        }
        if (scannerLine != null && !scannerLine.isRecycled()) {
            scannerLine.recycle();
        }
        if (srcCircleBitmap != null && !srcCircleBitmap.isRecycled()) {
            srcCircleBitmap.recycle();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        finish();
    }
}